package cn.dfusion.blockchain.repo;

import cn.dfusion.blockchain.BlockChainException;
import cn.dfusion.blockchain.PropertiesConfigurator;
import cn.dfusion.blockchain.entity.Message;
import cn.dfusion.blockchain.entity.TransactionInfo;
import cn.dfusion.blockchain.utils.BeanUtils;
import cn.dfusion.blockchain.utils.TimeUtils;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @ClassName: BlockChainProvider
 * @Description: 区块链供应类，基于RPC接口封装
 * @author ipenta
 * @date 2017年4月6日 下午12:21:28
 *
 */
@Component
public class BlockChainProvider {

	private static final Logger logger = LoggerFactory.getLogger(BlockChainProvider.class);

	@Autowired
	private BlockChainClient blockChainClient;

	@Autowired
	private PropertiesConfigurator propertiesConfigurator;

	// 创建记录，参数:object
	public <T> String createTx(String txType, T t) throws BlockChainException {
		Map<String, String> data = BeanUtils.beanTomap(t);
		return createTx(txType, data);
	}

	// 创建记录，参数:object
	public <T> String createTx(String txType, T t, String referTxHash) throws BlockChainException {
		Map<String, String> data = BeanUtils.beanTomap(t);
		logger.debug("createTx:referTxHash:{}", data);
		return createTx(txType, data, referTxHash);
	}

	// 创建记录，参数:object
	public <T> String createTx(String txType, T t, String referTxHash, List<String> authorizedUpdaters)
			throws BlockChainException {
		Map<String, String> data = BeanUtils.beanTomap(t);
		return createTx(txType, data, referTxHash);
	}

	// 创建记录，参数:map
	public String createTx(String txType, Map<String, String> map) throws BlockChainException {
		logger.debug(JSON.toJSONString(map));
		return createTx(txType, map, null, new ArrayList<String>());
	}

	// 创建记录，参数:map
	public String createTx(String txType, Map<String, String> map, String referTxHash) throws BlockChainException {
		return createTx(txType, map, referTxHash, new ArrayList<String>());
	}

	// 创建记录，参数:map
	public String createTx(String txType, Map<String, String> map, String referTxHash, List<String> authorizedUpdaters)
			throws BlockChainException {

		long timestamp = TimeUtils.getTxTimestamp();
		logger.debug("time:{}",timestamp);
		String publick_key = propertiesConfigurator.getPublicKey();
		String private_key = propertiesConfigurator.getPrivateKey();
		logger.debug("method:createTx:map as {}", map);
		String sign = messageConverter(
				blockChainClient.sign2(txType, map, timestamp, referTxHash, authorizedUpdaters, private_key));
		String archiveHash = messageConverter(
				blockChainClient.archive2(txType, map, timestamp, publick_key, sign, referTxHash, authorizedUpdaters));
		logger.debug("method:creatTx as {}", archiveHash);
		return archiveHash+","+timestamp;
	}
	
	/**
	 * @param txHash
	 */
	@Async
	public TransactionInfo findTransactionInfoByHash(String txHash) {
		return messageConverter(blockChainClient.lookupTxByHash(txHash));
	}

	// 查找记录,列表接口
	@Async
	public List<TransactionInfo> findTransactionInfoList(String txType, Map<String, String> filter) throws BlockChainException {
		logger.debug("method:findRecord:filter:{}", JSON.toJSONString(filter));
		return messageConverter(blockChainClient.lookupTxByKey(txType, filter));
	}

	// 数据转换
	private <T> T messageConverter(Message<T> message) {
		if (message.getStatus().equals(Message.Status.SUCCESS.getValue())) {
			return message.getData();
		} else {
			throw new BlockChainException(message.getErrorContent());
		}
	}

	

	
}
